package com.jbm;

import com.google.gson.*;
import org.apache.commons.lang.SystemUtils;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by root on 18-6-8.
 */
public class BridgeHnadler extends IoHandlerAdapter
{
	protected static Logger logger = LoggerFactory.getLogger(BridgeHnadler.class);

	public static Resource b_pool = new Resource(20,"b_ppol");

	public static Map<String,ConnectAgent> b_server_ca = new HashMap<String, ConnectAgent>();
	public static final Object b_server_ca_mutex = new Object();
	public static Map<String,ConnectAgent> b_client_ca = new HashMap<String, ConnectAgent>();

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception
	{
		cause.printStackTrace();
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception
	{
		JsonParser parser = new JsonParser();
		logger.info("recv:"+(String)message);
		JsonObject msg = (JsonObject) parser.parse((String)message);

		JsonElement je_type = msg.get("j_type");

		if ( je_type != null )
			if ( je_type.toString().equals("\"request\"")||
					je_type.toString().equals("\"uprequest\""))
			{
				SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG,"Recv:%s",(String)message);

				JsonElement je_content = msg.get("content");
				String wy_code = msg.get("wy_code").getAsString();

				String response = null;

				ConnectAgent ca = b_client_ca.get(wy_code);

				if ( ca == null )
					response = HttpHandler.BuildError(500,"wrong wy_code");
				else if ( ca.getM_iosession() != session )
					response = HttpHandler.BuildError(500,"wrong iosession");
				else
				{
					try
					{
						Class doproc = Class.forName("com.jbm."+wy_code);
						DoProcess dp = (DoProcess)doproc.newInstance();
						if ( je_type.toString().equals("\"request\"") )
							response = dp.Proc(je_content.getAsString());
						else if ( je_type.toString().equals("\"uprequest\"") )
							response = dp.UNPay(je_content.getAsString());
					}catch (Exception e)
					{
						response = HttpHandler.BuildError(500,e.getMessage());
					}
				}

				String je_response = HttpHandler.BuildResponse(response, msg.get("sequence").getAsString());

				session.write(je_response);
			}else if ( je_type.toString().equals("\"response\""))
			{
				JsonElement je_seq = msg.get("sequence");

				P2PDialog dialog = (P2PDialog)HttpHandler.m_dialogqueue.Get(new ResKey(je_seq.getAsString()),null);

				if ( dialog != null )
				{
					logger.info("find bridge dialog...");

					JsonElement je_content = msg.get("content");

					dialog.Put(je_content.getAsString());
				} else
				{
				}
			}else if ( je_type.toString().equals("\"hello\""))
			{
				if ( GServer.g_server_type == GServer.Server_Type_Gate )
				{
					ConnectAgent ca = new ConnectAgent(0, ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress(),
							((InetSocketAddress) session.getRemoteAddress()).getPort(),
							((InetSocketAddress) session.getLocalAddress()).getPort(),
							ConnectAgent.CA_Type_Json_Server);

					ca.setM_iosession(session);
					ca.Born(3, 5000);
					ca.setM_keepalive(true);
					b_pool.Add(ca);

					String wy_code = msg.get("wy_code").getAsString();
					ca.wy_code = wy_code;
					session.setAttribute("CA_Key", ca);

					synchronized (b_server_ca_mutex)
					{
						SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG, "b_server_ca set %s ca:%s",wy_code,ca.getM_lifename().toString());
						b_server_ca.put(wy_code,ca);
					}
				}
			}

		ConnectAgent ca = (ConnectAgent)session.getAttribute("CA_Key");

		ca.IamLiving();
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception
	{
		logger.info("客户端与服务端创建连接...port:" + ((InetSocketAddress) session.getRemoteAddress()).getPort());

		SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG,"Bridge New Connection Create");
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG,"Bridge Session Close");

		if ( GServer.g_server_type == GServer.Server_Type_Gate )
		{
			ConnectAgent ca = (ConnectAgent) session.getAttribute("CA_Key");

			if ( ca != null )
			{
				String wy_code = ca.wy_code;

				ca.ReleaseFromPool();

				synchronized (b_server_ca_mutex)
				{
					ConnectAgent sca = b_server_ca.get(wy_code);

					if (ca == sca)
					{
						SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG, "%s b_server_ca set null ca:%s", wy_code, ca.getM_lifename().toString());
						b_server_ca.remove(wy_code);
					} else
						SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_DEBUG, "%s ca is not current ca:%s", wy_code, ca.getM_lifename().toString());
				}
			}
		}
	}
}
